import os
import xml.etree.ElementTree as ET
import socket
import re

import paramiko

from PyQt5.QtGui import QTextCharFormat, QColor
from PyQt5.QtWidgets import QMessageBox

import utils


class FileUtils:
    def __init__(self):
        print(self)
        # prefix = "10.1."
        # code_arr = utils.divide_code(code)
        # if code_arr[1].startswith("0"):
        #     station_code = code_arr[1][:1]
        # else:
        #     station_code = code_arr[1]
        # device_code = code_arr[2]
        # hostname = f"{prefix}{station_code}.{device_code}"  # "10.1.100.130"
        # username = 'root'
        # password = 'afcsle'
        # self.ssh_client = self.ssh_connect(hostname, username, password)

    # 读取本地文件
    @staticmethod
    def read_local_xml(self, file_path):
        try:
            with open(file_path, "r") as f:
                return f.read()
        except Exception as e:
            print("无法读取本地XML文件：", e)
            return None

    @staticmethod
    def ssh_connect(self, code):
        print(code)
        # prefix = "10.1."
        # code_arr = utils.divide_code(code)
        # if code_arr[1].startswith("0"):
        #     station_code = code_arr[1][:1]
        # else:
        #     station_code = code_arr[1]
        # device_code = code_arr[2]
        hostname = "10.1.100.130"  # f"{prefix}{station_code}.{device_code}"  # "10.1.100.130"
        username = 'root'
        password = 'afcsle'
        ssh_client = paramiko.SSHClient()
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_client.connect(hostname, username=username, password=password)
        return ssh_client

    # ssh读取远程文件
    @staticmethod
    def read_remote_xml(ssh_client, remote_file_path):
        # SSH connection details
        # prefix = "10.1."
        # code_arr = utils.divide_code(code)
        # if code_arr[1].startswith("0"):
        #     station_code = code_arr[1][:1]
        # else:
        #     station_code = code_arr[1]
        # device_code = code_arr[2]
        # hostname = f"{prefix}{station_code}.{device_code}"  # "10.1.100.130"
        # username = 'root'
        # password = 'afcsle'

        # Remote file path
        # remote_file_path = '/home/AFC/tvm/Config/SysSetting.xml'
        remote_crontab_path = '/var/spool/cron/root'
        # Connect to remote host

        try:
            # ssh_client = ssh_connect(ip_address, username, password)
            # ssh_client = paramiko.SSHClient()
            # ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            # ssh_client.connect(hostname, username=username, password=password)
            # Read current content
            stdin, stdout, stderr = ssh_client.exec_command(f'cat {remote_file_path}')
            current_content = stdout.read().decode('utf-8')
            print("current_content:")
            print(current_content)

            return current_content

            # Modify the content
            # modified_content = current_content.replace('多元二维码支付地址33333333', "多元二维码支付地址")
            # print("current_content:")
            # print(modified_content)
            # # Write modified content back to file
            # escaped_modified_content = modified_content.replace('"', r'\"')
            # stdin, stdout, stderr = ssh_client.exec_command(f'echo "{escaped_modified_content}" > {remote_file_path}')
            # print(stdout.read().decode('utf-8'))

            # crontab -e
            # stdin, stdout, stderr = ssh_client.exec_command(f'cat {remote_crontab_path}')
            # current_content = stdout.read().decode('utf-8')
            # print(current_content)
            # update_crontab(time, ssh_client)
            # ssh_client.close()
        except Exception as e:
            print(f"Error: {e}")
        finally:
            ssh_client.close()

    @staticmethod
    def remote_reboot(self, ssh_client):
        try:
            # Execute the reboot command
            stdin, stdout, stderr = ssh_client.exec_command("sudo reboot")

            # Wait for the command to complete
            exit_status = stdout.channel.recv_exit_status()

            if exit_status == 0:
                print("Reboot command executed successfully.")
            else:
                print(f"Reboot command failed with exit status: {exit_status}")

        except paramiko.AuthenticationException as auth_error:
            print(f"Authentication failed: {auth_error}")
        except paramiko.SSHException as ssh_error:
            print(f"SSH connection failed: {ssh_error}")
        except Exception as e:
            print(f"An error occurred: {e}")
        finally:
            ssh_client.close()

    # 检测是否符合规则
    # content文件类容 code 用户输入编码
    @staticmethod
    def check_and_modify_settings(self, content, code):
        errors_dict_dev = {"line": 0}  # dev标签里的错误内容
        errors_dict_ftp = {"line": 1}  # ftp标签里的错误内容
        errors_dict_sc = {"line": 2}
        errors_dict_acc = {"line": 3}
        errors_dict_cash = {"line": 4}
        errors = []
        infos = utils.divide_code(code)
        station_code = infos[1]  # 取出站点编号，IP修改都是依据点这个
        root = ET.fromstring(content)
        # dev
        dev_element = root.find(".//dev")
        dev_gatway = dev_element.get("gateWay").split(".")[2]
        if station_code != dev_gatway:
            errors_dict_dev["gateWay"] = dev_element.get("gateWay")
        dev_code = dev_element.get('code')
        if code != dev_code:
            errors_dict_dev["code"] = dev_element.get("code")
        dev_ip = dev_element.get('ip').split(".")[2]
        if dev_ip != station_code:
            errors_dict_dev["ip"] = dev_element.get('ip')

        # ftp
        ftp_element = root.find(".//ftp")
        ftp_ip = ftp_element.get('ip')
        if station_code != ftp_element.get('ip').split(".")[2]:
            errors_dict_ftp["ip"] = ftp_ip

        # sc
        sc_element = root.find(".//sc")
        sc_code = sc_element.get('code')
        sc_ip = sc_element.get('ip')
        if code != sc_code:
            errors_dict_sc['code'] = sc_code
        if station_code != sc_element.get('ip').split(".")[2]:
            errors_dict_sc['ip'] = sc_element.get('ip')

        # acc
        acc_element = root.find(".//acc")
        acc_code = acc_element.get('code')
        if code != acc_code:
            errors_dict_acc['code'] = acc_code
        # cash
        cash_element = root.find(".//cashcoin")
        if cash_element is not None:
            cash_enabled = cash_element.get("enabled")
            if cash_enabled == "1":
                errors_dict_cash['enabled'] = "1"

        if len(errors_dict_dev) > 1:
            errors.append(errors_dict_dev)
        if len(errors_dict_ftp) > 1:
            errors.append(errors_dict_ftp)
        if len(errors_dict_sc) > 1:
            errors.append(errors_dict_sc)
        if len(errors_dict_acc) > 1:
            errors.append(errors_dict_acc)
        if len(errors_dict_cash) > 1:
            errors.append(errors_dict_cash)
        return errors

        # if port != "8888":
        #     print("设置不正确，需要进行修改！")
        #     return None
        # else:
        #     print("设置正确，无需修改。")
        #     return None

    @staticmethod
    def replace_attribute_value(self, xml_string, element_name, attribute_name, new_value):
        root = ET.fromstring(xml_string)

        for element in root.findall(element_name):
            current_value = element.get(attribute_name)
            if current_value is not None:
                element.set(attribute_name, new_value)

        modified_xml = ET.tostring(root, encoding="UTF-8", xml_declaration=True).decode("UTF-8")
        return modified_xml

    # 修改文件类容
    @staticmethod
    def replace_file_content(self, file_path, new_content):
        with open(file_path, "w") as file:
            file.write(new_content)

    # 更新bom 内容
    @staticmethod
    def update_bom_value(key, new_value, content):
        lines = content.splitlines()
        updated_lines = []

        for line in lines:
            if '=' in line:
                line_key, line_value = line.split('=', 1)
                if line_key.strip() == key:
                    line = f"{line_key}={new_value}"
            updated_lines.append(line)

        updated_content = '\n'.join(updated_lines)
        return updated_content

    # 更新远程文件
    @staticmethod
    def update_remote_file(modified_content, ssh_client, remote_file_path):
        # Write modified content back to file
        escaped_modified_content = modified_content.replace('"', r'\"')
        stdin, stdout, stderr = ssh_client.exec_command(f'echo "{escaped_modified_content}" > {remote_file_path}')
        print(stdout.read().decode('utf-8'))

    # 更新本地文件内容
    def update_file(self, file_path, new_content, permissions=None):
        try:
            if permissions is not None:
                os.chmod(file_path, permissions)
                with open(file_path, "w") as file:
                    file.write(new_content)
                print("File content and permissions updated successfully.")
                utils.show_message(self, title="恭喜😄", content="更新文件成功")
            else:
                utils.show_message(self, title="倒霉😓", content="更新文件失败")
        except OSError as e:
            utils.show_message(self, title="倒霉😓", content="发生意想不到的问题")
            print(f"Error updating file: {e}")

    # 修改对应标签内容
    @staticmethod
    def modify_xml_content(self, xml_content, tag, new_value):
        try:
            root = ET.fromstring(xml_content)

            for d in root.findall('d'):
                t_element = d.find('t')
                v_element = d.find('v')

                if t_element is not None and v_element is not None and t_element.text == tag:
                    v_element.text = new_value
                    return ET.tostring(root, encoding='utf-8').decode()

            print(f"Tag '{tag}' not found in the XML.")
            return None
        except Exception as e:
            print("An error occurred:", str(e))
            return None

    # 将xml文件格式化为字典
    @staticmethod
    def parse_xml_to_dict(self, xml_string):
        root = ET.fromstring(xml_string)
        data_dict = {}

        for d_element in root.findall("d"):
            t_element = d_element.find("t")
            v_element = d_element.find("v")
            if t_element is not None and v_element is not None:
                key = t_element.text
                value = v_element.text
                data_dict[key] = value

        return data_dict

    # 解析Bom-config 61 10 03 151
    @staticmethod
    def parse_bom_file_to_dict(self, setting_text):
        settings = {}
        lines = setting_text.strip().split('\n')
        current_section = None
        for line in lines:
            line = line.strip()
            if line.startswith('[') and line.endswith(']'):
                current_section = line[1:-1]
                settings[current_section] = {}
            elif current_section is not None and '=' in line:
                key, value = line.split('=')
                settings[current_section][key] = value

        return settings

    @staticmethod
    def update_crontab(new_number, ssh_client):
        pattern = r'\*/\d+'
        # Folder path
        remote_folder_path = '/var/spool/cron/'
        sftp = ssh_client.open_sftp()
        remote_files = sftp.listdir(remote_folder_path)
        for remote_file in remote_files:
            remote_file_path = remote_folder_path + remote_file

            # Read the file
            with sftp.file(remote_file_path, 'r') as file:
                file_content = file.read().decode('utf-8')
                print("The old file:")
                print(file_content)

            # Modify the content using regex
            updated_content = re.sub(pattern, f'*/{new_number}', file_content)

            # Write the updated content back to the file
            with sftp.file(remote_file_path, 'w') as file:
                file.write(updated_content)

            print(f"File {remote_file} updated successfully.")
        sftp.close()
        ssh_client.close()
